import { Euler, Vector3, Camera } from "three"
import clientEnum from "./client.enum"
import clientFunc from "./client.func"
const J = {
  sweep: "",
  mode: clientEnum.H.Mode.DOLLHOUSE,
  position: { x: 0, y: 0, z: 0 },
  rotation: { x: 0, y: 0 },
  projection: new Float32Array(16)
}
const G = Math.PI / 180
export default class CoordinateConverter {
  tempEuler: any
  tempPosition: any
  camera: any
  cameraPose: any
  constructor() {
    ;(this.tempEuler = new Euler()), (this.tempPosition = new Vector3()), (this.camera = new Camera()), (this.cameraPose = null)
  }
  setCameraFromPose(t) {
    if (this.cameraPose && clientFunc.U(this.cameraPose, t)) return
    ;(this.cameraPose = this.cameraPose || J), clientFunc.F(this.cameraPose, t)
    const e = t.position
    this.camera.position.set(e.x, e.y, e.z)
    const s = t.rotation
    this.tempEuler.set(s.x * G, s.y * G, 0, "YXZ"),
      this.camera.quaternion.setFromEuler(this.tempEuler),
      this.camera.updateMatrixWorld(),
      this.camera.projectionMatrix.fromArray(t.projection).transpose()
  }
  worldToNDC(t, e) {
    return (
      this.tempPosition.set(t.x, t.y, t.z),
      this.tempPosition.project(this.camera),
      ((e = e || { x: 0, y: 0, z: 0 }).x = this.tempPosition.x),
      (e.y = this.tempPosition.y),
      (e.z = this.tempPosition.z),
      e
    )
  }
  worldToScreen(t, e, s) {
    return (
      ((s = this.worldToNDC(t, s)).x = 0.5 * (this.tempPosition.x + 1) * e.w),
      (s.y = -0.5 * (this.tempPosition.y - 1) * e.h),
      t.z < -1 && ((s.x *= -1), (s.y *= -1)),
      s
    )
  }
}
